/**
 * each component can be replaced by setting 
 * mini:modelValueLoader=${var}, mini:modelValueVerifier=${var},
 * mini:displayValueGetter=${var}, and mini:displayValueSetter=${var}
 * attributes temporarily
 */
define(['mini/flow/DefaultModelValueLoader', 'mini/flow/DefaultModelValueVerifier', 'mini/flow/DefaultDisplayValueGetter', 'mini/flow/DefaultDisplayValueSetter'], function(
    DefaultModelValueLoader, DefaultModelValueVerifier, DefaultDisplayValueGetter, DefaultDisplayValueSetter) {
    return function(_modelValueLoader, _modelValueVerifier, _displayValueGetter, _displayValueSetter) {
        var modelValueLoader = (_modelValueLoader) ? _modelValueLoader : new DefaultModelValueLoader();
        var modelValueVerifier = (_modelValueVerifier) ? _modelValueVerifier : new DefaultModelValueVerifier();
        var displayValueGetter = (_displayValueGetter) ? _displayValueGetter : new DefaultDisplayValueGetter();
        var displayValueSetter = (_displayValueSetter) ? _displayValueSetter : new DefaultDisplayValueSetter();

        function execute(context) {
            var __modelValueLoader = (context.element.hasAttribute("mini:modelValueLoader")) ? (eval(context.element.getAttribute("mini:modelValueLoader"))) : modelValueLoader;
            var __modelValueVerifier = (context.element.hasAttribute("mini:modelValueVerifier")) ? (eval(context.element.getAttribute("mini:modelValueVerifier"))) : modelValueVerifier;
            var __displayValueGetter = (context.element.hasAttribute("mini:displayValueGetter")) ? (eval(context.element.getAttribute("mini:displayValueGetter"))) : displayValueGetter;
            var __displayValueSetter = (context.element.hasAttribute("mini:displayValueSetter")) ? (eval(context.element.getAttribute("mini:displayValueSetter"))) : displayValueSetter;
            __modelValueLoader.execute(context);
            for (var key in context.modelValue) {
                if (!__modelValueVerifier.execute(context, key)) {
                    return false;
                }
            }
            __displayValueGetter.execute(context);
            __displayValueSetter.execute(context);
            return true;
        }

        function shouldProcess(context) {
            return context.element.hasAttribute("mini:value") || (context.element.hasAttribute("mini:text"));
        }
        function shouldProcessChildNodes(context) {
            return true;
        }

        this.shouldProcess = shouldProcess;
        this.shouldProcessChildNodes = shouldProcessChildNodes;

        this.execute = execute;
        this.modelValueLoader = modelValueLoader;
        this.modelValueVerifier = modelValueVerifier;
        this.displayValueGetter = displayValueGetter;
        this.displayValueSetter = displayValueSetter;
        return this;
    }
});